﻿Imports Runa.UI.Controls
Imports Runa.UI.Threading
Imports Microsoft.Xna.Framework.Graphics
Imports Microsoft.Xna.Framework
Imports Runa.Foundation.Messaging
Imports Runa.Core.Services

Namespace Global.Runa.UI.Compoents

    Public Class Frame
        Inherits DrawableGameComponent
        Implements IMessageFilter

        Public Property Content As Page
        Public Property Dispatcher As Dispatcher
        Public Property Name As String
        Public Property SpriteBatch As SpriteBatch
        Public Property Window As GameWindow

        Private m_graphics As GraphicsDeviceManager

        Public ReadOnly Property Controls() As Dictionary(Of String, UIElementBase)
            Get
                Dim dic As New Dictionary(Of String, UIElementBase)
                For Each item In SafeNativeMethods.Hwnds
                    If TypeOf item Is UIElementBase Then
                        With CType(item, UIElementBase)
                            If .Frame Is Me Then
                                dic.Add(.Name, item)
                            End If
                        End With
                    End If
                Next
                Return dic
            End Get
        End Property

        Friend ReadOnly Property SafeNativeMethods() As ISafeNativeMethods
            Get
                Return Me.Game.Services.GetService(GetType(ISafeNativeMethods))
            End Get
        End Property

        Friend ReadOnly Property GameParameterService() As IGameParameterService
            Get
                Return Me.Game.Services.GetService(GetType(IGameParameterService))
            End Get
        End Property

        Public Sub New(ByVal g As Game)
            MyBase.New(g)
            Me.m_graphics = GameParameterService.Graphics
            g.Components.Add(Me)
            SafeNativeMethods.RegisterWindowClass(Me)
            Me.Window = g.Window
            MyBase.Enabled = True
            MyBase.Visible = True
            Me.Dispatcher = New Dispatcher(g)
            Threading.Dispatcher.Run()
            Me.SpriteBatch = New SpriteBatch(g.GraphicsDevice)        
        End Sub

        Public Function FindControl(ByVal Name As String) As UIElementBase
            Return Me.Content.FindControl(Name)
        End Function

        Public Function FindControl(ByVal typ As Type) As List(Of UIElementBase)
            Return Me.Content.FindControl(typ)
        End Function

        Public Function IsSubControl(ByVal obj As UIElementBase) As Boolean
            Return Me.Content.IsSubControl(obj)
        End Function

        Public Function GetLevel(ByVal ctrl As UIElementBase) As Integer
            If Me.IsSubControl(ctrl) Then
                Dim i As Integer = 1
                While ctrl IsNot Me.Content
                    ctrl = ctrl.Parent
                    i += 1
                End While
                Return i
            Else
                Return -1
            End If
        End Function

        Public Sub Navigation(ByVal page As Page)
            Me.Navigation(page, New Navigation.NavigationContext())
        End Sub

        Public Sub Navigation(ByVal page As Page, ByVal e As Navigation.NavigationContext)
            SafeNativeMethods.RegisterWindowClass(page)
            Dim oldPage As Page = Me.Content
            Me.Content = page
            page.Frame = Me
            page.Size = New Vector2(Me.m_graphics.PreferredBackBufferWidth, Me.m_graphics.PreferredBackBufferHeight)
            page.Visible = True
            page.IsActive = True
            If oldPage IsNot Nothing Then oldPage.IsActive = False
            page.OnNavigatedTo(oldPage, e)
            'If (Not oldPage Is Nothing) Then
            '    oldPage.Dispose()
            'End If
        End Sub

        Public Overrides Sub Update(ByVal gameTime As GameTime)
            If (Not Me.Content Is Nothing) Then
                Me.Content.Update(gameTime)
            End If
            MyBase.Update(gameTime)            
        End Sub

        Public Overrides Sub Draw(ByVal gameTime As GameTime)
            If (Not Me.Content Is Nothing) Then
                Me.Content.Draw(Me.SpriteBatch)
            End If
            MyBase.Draw(gameTime)
        End Sub

        Public Function DispachMessage(ByRef m As Foundation.Messaging.Message) As Boolean Implements Foundation.Messaging.IMessageFilter.DispachMessage
            Return True
        End Function

        Public Function PreFilterMessage(ByRef m As Foundation.Messaging.Message) As Boolean Implements Foundation.Messaging.IMessageFilter.PreFilterMessage
            Return True
        End Function

        Public Function TranslateMessage(ByRef m As Foundation.Messaging.Message) As Boolean Implements Foundation.Messaging.IMessageFilter.TranslateMessage
            Return True
        End Function

        Public Function WndProc(ByRef m As Foundation.Messaging.Message) As Boolean Implements Foundation.Messaging.IMessageFilter.WndProc
            Return CType(Me.Dispatcher, IMessageFilter).WndProc(m)
        End Function

    End Class

End Namespace